import React, { useEffect, useRef, useState } from 'react';
import {
  Down,
  // FixZAsix,
  Home,
  Left,
  Right,
  RotateL,
  RotateR,
  Up,
} from './icon';
import './index.css';
import {
  Direction,
  IViewCube,
  animate,
  createViewCubeHandler,
  rotateIt,
} from '@amcax/web-render';

export interface ViewCubeParam {
  /**
   * 对应渲染场景的camera，用于联动视角
   */
  camera: any;
  /**
   * 联动的控制器
   */
  controls: any;
  /**
   * 回调函数，调整视角到合适位置
   */
  fitView?: () => Promise<void>;
  /**
   * view cube 的尺寸（默认宽高一致）
   */
  size?: number;
}
export function ViewCube({
  camera,
  controls,
  fitView,
  size = 180,
}: ViewCubeParam) {
  const rotateComplete = useRef(true); // cube旋转完成=>可旋转状态
  const viewCubeDom = useRef(null);
  const [viewCubeHandler, setViewCubeHandler] = useState<IViewCube>(null);

  useEffect(() => {
    let updateCubeControl: VoidFunction;

    if (viewCubeHandler) {
      updateCubeControl = () => {
        if (viewCubeHandler) {
          viewCubeHandler.root.quaternion.setFromRotationMatrix(
            camera.matrixWorldInverse,
          );
          viewCubeHandler.renderer.render(
            viewCubeHandler.scene,
            viewCubeHandler.camera,
          );
        }
      };
      viewCubeHandler.onAngleChange((normal, up) => {
        animate(
          camera,
          controls.target,
          function (object) {
            controls.applyRotateInfo(object);
          },
          normal,
          up,
        );
      });
      // 当渲染场景中，发生旋转等，同步更新ViewCube
      controls.addEventListener('change', updateCubeControl);
      // 初始化成功之后，更新一次；使得ViewCube和视窗的视角一致
      updateCubeControl();
    }

    return () => {
      viewCubeHandler && viewCubeHandler.renderer.dispose();
      updateCubeControl &&
        controls.removeEventListener('change', updateCubeControl);
    };
  }, [viewCubeHandler]);

  useEffect(() => {
    if (viewCubeDom.current) {
      const inst = createViewCubeHandler(size, viewCubeDom.current, camera);
      setViewCubeHandler(inst);
    }
  }, [viewCubeDom]);
  const handleButtonClick = async (
    e: React.MouseEvent<HTMLButtonElement, MouseEvent>,
    direction: Direction,
  ) => {
    e.stopPropagation();
    e.nativeEvent.stopImmediatePropagation();
    if (!rotateComplete.current) {
      return;
    }
    rotateComplete.current = false;
    if (direction === Direction.home) {
      // 有fit动画，且同步旋转模型，应该是 异步函数
      await fitView?.();
    } else {
      await rotateIt(direction, camera, controls);
    }
    rotateComplete.current = true;
  };
  return (
    <div
      id='cube-scene'
      style={{ position: 'absolute', width: size, height: size }}
      ref={viewCubeDom}
      onContextMenu={(e) => e.preventDefault()}
      onMouseUp={(e) => {
        e.stopPropagation();
        e.nativeEvent.stopImmediatePropagation();
      }}>
      {fitView && (
        <button
          className='cube-button icon-btn home'
          onClick={async (e) => {
            await handleButtonClick(e, Direction.home);
          }}>
          <Home />
        </button>
      )}
      <div className='arrow-wrapper'>
        <button
          className='r-l cube-button icon-btn'
          onClick={async (e) => {
            await handleButtonClick(e, Direction.rotateLeft);
          }}>
          <RotateL />
        </button>
        <button
          className='up cube-button icon-btn'
          onClick={async (e) => {
            await handleButtonClick(e, Direction.up);
          }}>
          <Up />
        </button>
        <button
          className='r-r cube-button  icon-btn'
          onClick={async (e) => {
            await handleButtonClick(e, Direction.rotateRight);
          }}>
          <RotateR />
        </button>
        {/* <Button
            className={
              isFixZ ? 'z-up cube-button selected' : 'z-up cube-button'
            }
            shape='circle'
            onMouseUp={() => fixZ(!isFixZ.valueOf())}
            icon={<FixZAsix />}
            ghost={!isFixZ}
          /> */}
        <button
          className='right cube-button icon-btn'
          onClick={async (e) => {
            await handleButtonClick(e, Direction.right);
          }}>
          <Right />
        </button>
        <button
          className='down cube-button icon-btn'
          onClick={async (e) => {
            await handleButtonClick(e, Direction.down);
          }}>
          <Down />
        </button>
        <button
          className='left cube-button icon-btn'
          onClick={async (e) => {
            await handleButtonClick(e, Direction.left);
          }}>
          <Left />
        </button>
      </div>
    </div>
  );
}
